package com.lisn.sg_fileupload;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.blankj.utilcode.util.UriUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import okhttp3.logging.HttpLoggingInterceptor;

/**
 * 文件上传下载demo
 */
public class MainActivity extends AppCompatActivity {

    private static final String TAG = MainActivity.class.getSimpleName();
    String baseUrl = "http://172.22.44.9:8080";
    private String path;
    private TextView tv_path;
    private OkHttpClient okhttp;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        EditText filenameEditText = findViewById(R.id.name);
        tv_path = findViewById(R.id.tv_path);
        ImageView view = findViewById(R.id.view);
        Button choose = findViewById(R.id.choosee);
        Button upload = findViewById(R.id.upload);
        Button download = findViewById(R.id.download);
        choose.setOnClickListener(v -> {
            chooseFile();
        });

        upload.setOnClickListener(v -> {
            if (TextUtils.isEmpty(path)) {
                showMessage("请先选择文件");
                return;
            }

            File file = new File(path);
            String name = file.getName();
            String path = file.getPath();

            String inputName = filenameEditText.getText().toString();
            if (!TextUtils.isEmpty(inputName)) {
                name = inputName;
            }
            Log.e(TAG, "onActivityResult: name = " + name);
            Log.e(TAG, "onActivityResult: path = " + path);

            if (uploadFile(path, name)) {
                showMessage("上传成功");
            } else {
                showMessage("上传失败");
            }
        });

        download.setOnClickListener(v -> {
            File file = downloadFile(filenameEditText.getText().toString());
            if (file == null)
                showMessage("没有这张图片");
            else {
                view.setImageURI(null);
                view.setImageURI(Uri.fromFile(file));
                showMessage("下载成功");
            }
        });
    }

    public void chooseFile() {
        //所需权限
        String[] permissions = new String[]{"android.permission.READ_EXTERNAL_STORAGE", "android.permission.WRITE_EXTERNAL_STORAGE"};
        //如果没有权限
        if (ActivityCompat.checkSelfPermission(this, permissions[0]) != PackageManager.PERMISSION_GRANTED
                || ActivityCompat.checkSelfPermission(this, permissions[1]) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, permissions, 1);//申请权限
        }

        Intent intent = new Intent(Intent.ACTION_GET_CONTENT); //使用系统的文件选择器
        intent.setType("*/*"); //所有类型的文件
        intent.addCategory(Intent.CATEGORY_OPENABLE); //期望获取的数据可以作为一个File打开
        startActivityForResult(intent, 1);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == Activity.RESULT_OK) {
            Uri uri = data.getData();
            Log.e(TAG, "onActivityResult: uri = " + uri);
            this.path = UriUtils.uri2File(uri).getPath();
            Log.e(TAG, "onActivityResult: path = " + path);

            tv_path.setText(path);


        }
    }

    public void showMessage(String message) {
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
    }


    public boolean uploadFile(String path, String filename) {
        if (okhttp == null) {
            okhttp = getOkHttpClient();
        }

        File file = new File(path);
        if (path.isEmpty() || !file.exists()) {
            Log.e(TAG, "uploadFile: ----文件不能为空");
            return false;
        }
        RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM)
                .addFormDataPart("file", filename, RequestBody.create(new File(path), MediaType.parse("multipart/form-data")))
                .addFormDataPart("filename", filename)
                .build();
        FutureTask<Boolean> task = new FutureTask<>(() -> {
            try {
                String url = baseUrl + "/upload";
                Request build = new Request.Builder().post(body).url(url).build();
                ResponseBody responseBody = okhttp.newCall(build).execute().body();
                Log.e(TAG, "uploadFile: responseBody = " + responseBody);
                if (responseBody != null)
                    return Boolean.parseBoolean(responseBody.string());
                return false;
            } catch (IOException e) {
                Log.e(TAG, "uploadFile: err = " + e.toString());
                return false;
            }
        });
        try {
            new Thread(task).start();
            return task.get();
        } catch (ExecutionException | InterruptedException e) {
            e.printStackTrace();
            Log.e(TAG, "uploadFile: err " + e.toString());
            return false;
        }
    }

    @NonNull
    private OkHttpClient getOkHttpClient() {
        OkHttpClient.Builder builder = new OkHttpClient.Builder();

        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
            @Override
            public void log(String message) {
                try {
                    if (message.length() < 300) {
                        message = URLDecoder.decode(message, "utf-8");
                    }
                    Log.e("OKHttp-----", message);
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                    Log.e("OKHttp-----", message);
                }
            }
        });

        // 这行必须加 不然默认不打印
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        builder.addInterceptor(interceptor);

        OkHttpClient okhttp = builder.build();
        return okhttp;
    }

    public File downloadFile(String filename) {
        if (okhttp == null) {
            okhttp = getOkHttpClient();
        }
        if (filename == null || filename.isEmpty())
            return null;

        RequestBody body = new MultipartBody.Builder().addFormDataPart("filename", filename).build();
        FutureTask<File> task = new FutureTask<>(() -> {
            Request request = new Request.Builder().post(body).url(baseUrl + "/download").build();
            ResponseBody responseBody = okhttp.newCall(request).execute().body();
            if (responseBody != null) {
                if (getExternalFilesDir(null) != null) {
                    File file = new File(getExternalFilesDir(null).toString() + "/" + filename);
                    try (
                            InputStream inputStream = responseBody.byteStream();
                            FileOutputStream outputStream = new FileOutputStream(file)
                    ) {
                        byte[] b = new byte[1024];
                        int n;
                        if ((n = inputStream.read(b)) != -1) {
                            outputStream.write(b, 0, n);
                            while ((n = inputStream.read(b)) != -1)
                                outputStream.write(b, 0, n);

                            if (inputStream != null) {
                                inputStream.close();
                            }
                            if (outputStream != null) {
                                outputStream.close();
                            }
                            return file;
                        } else {
                            file.delete();
                            return null;
                        }
                    }
                }
            }
            return null;
        });
        try {
            new Thread(task).start();
            return task.get();
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
            return null;
        }
    }
}